package com.hqd.jjvm.jnative.security;

import com.hqd.jjvm.jnative.JNativeRegistry;
import com.hqd.jjvm.rtda.JThread;
import com.hqd.jjvm.rtda.LocalVars;
import com.hqd.jjvm.rtda.heap.JMethod;
import com.hqd.jjvm.rtda.obj.JObject;

public class JAccessControllerNativeRegistry extends JNativeRegistry {
    private static final JAccessControllerNativeRegistry instance = new JAccessControllerNativeRegistry();
    protected static final String CLASS_PATH = "java/security/AccessController";

    static {
        registry(CLASS_PATH, "doPrivileged", "(Ljava/security/PrivilegedAction;)Ljava/lang/Object;", JAccessControllerNativeRegistry::doPrivileged);
        registry(CLASS_PATH, "doPrivileged", "(Ljava/security/PrivilegedExceptionAction;)Ljava/lang/Object;", JAccessControllerNativeRegistry::doPrivileged);
        registry(CLASS_PATH, "getStackAccessControlContext", "()Ljava/security/AccessControlContext;", JAccessControllerNativeRegistry::getStackAccessControlContext);
    }

    protected static void getStackAccessControlContext(JThread jThread) {
        jThread.getJvmStack().pushOperandStackRefVal(null);
    }

    protected static void doPrivileged(JThread jThread) {
        LocalVars localVars = jThread.getJvmStack().getTop().getLocalVars();
        JObject ref = localVars.getRefVal(0);
        jThread.getJvmStack().pushOperandStackRefVal(ref);
        JMethod method = ref.getJClass().getJMethod("run", "()Ljava/lang/Object;");
        jThread.createStackFrame(method);
    }

    public static JAccessControllerNativeRegistry getInstance() {
        return instance;
    }
}
